using System.Collections;
using System.Diagnostics.CodeAnalysis;

namespace RSCore;

public class EnumManager<T> : IReadOnlyDictionary<string, T>
	where T : unmanaged, Enum
{
	public static EnumManager<T> Shared
	{
		get
		{
			return instance ??= new EnumManager<T>();
		}
	}

	public int Count => mapping.Count;

	public IEnumerable<string> Keys => mapping.Keys;

	public IEnumerable<string> Names => mapping.Keys;

	public IEnumerable<T> Values => mapping.Values;

	public T this[string key] => mapping[key];

	public IEnumerable<T> this[Func<T, bool> predicate] => mapping.Values.Where(predicate);

	public bool ContainsKey(string key)
	{
		return mapping.ContainsKey(key);
	}

	public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
	{
		return mapping.GetEnumerator();
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)mapping).GetEnumerator();
	}

	public bool TryGetValue(string key, [MaybeNullWhen(false)] out T value)
	{
		return mapping.TryGetValue(key, out value);
	}

	private EnumManager()
	{
		mapping = new Dictionary<string, T>(
			from v in typeof(T).GetEnumValues().Cast<T>()
			select new KeyValuePair<string, T>(v.ToString(), v));
	}

	private static EnumManager<T>? instance;
	private readonly IReadOnlyDictionary<string, T> mapping;
}